﻿using IdentityServer4.AccessTokenValidation;
using JuCheap.Core.Infrastructure.Extentions;
using JuCheap.Core.Infrastructure.Utilities;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using System;
using System.IO;
using System.Linq;
using System.Net;
using System.Text.Encodings.Web;
using System.Text.Json;

namespace JuCheap.Core.Infrastructure.Web
{
    /// <summary>
    /// JuCheap Web 基础服务提供者
    /// </summary>
    public static class JuCheapWebService
    {
        /// <summary>
        /// CorsName
        /// </summary>
        public const string CorsName = "Cors";

        /// <summary>
        /// 获取json配置
        /// </summary>
        /// <returns></returns>
        public static JsonSerializerOptions GetJuCheapJsonOptions()
        {
            var jsonOptions = new JsonSerializerOptions
            {
                //增加默认json序列化的编码规则，避免中文乱码
                Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
                //驼峰式名称转换
                PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            };
            //日期格式化转换器
            jsonOptions.Converters.Add(new DatetimeJsonConverter());

            return jsonOptions;
        }

        /// <summary>
        /// 添加json.net的配置转换规则
        /// </summary>
        /// <param name="mvcBuilder"></param>
        public static void AddJuCheapJsonConfig(this IMvcBuilder mvcBuilder)
        {
            mvcBuilder.AddJsonOptions(config =>
            {
                //增加默认json序列化的编码规则，避免中文乱码
                config.JsonSerializerOptions.Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping;
                //驼峰式名称转换
                config.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
                //日期格式化转换器
                config.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
            });
        }

        /// <summary>
        /// 注册当前用户服务
        /// </summary>
        /// <param name="services"></param>
        public static void AddCurrentUserService(this IServiceCollection services)
        {
            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddScoped<ICurrentUserService, CurrentUserService>();
        }

        /// <summary>
        /// 添加Swagger服务
        /// </summary>
        /// <param name="services"></param>
        public static void AddJuCheapSwaggerService(this IServiceCollection services)
        {
            services.AddSwaggerGen(option =>
            {
                option.SwaggerDoc("sparktodo", new OpenApiInfo
                {
                    Version = "v1",
                    Title = "JuCheap API",
                    Description = "API for JuCheap",
                    Contact = new OpenApiContact() { Name = "JuCheap", Email = "service@jucheap.com" }
                });

                // 批量注释文件添加
                var xmlFiles = new DirectoryInfo(AppContext.BaseDirectory).GetFiles("*.xml");
                foreach (var file in xmlFiles)
                {
                    option.IncludeXmlComments(file.FullName, true);
                }

                //Token认证配置
                option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                {
                    Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                });
                option.AddSecurityRequirement(new OpenApiSecurityRequirement
                {
                    { 
                        new OpenApiSecurityScheme
                        {
                            Reference = new OpenApiReference()
                            {
                                Id = "Bearer",
                                Type = ReferenceType.SecurityScheme
                            }
                        }, Array.Empty<string>() 
                    }
                });
            });
        }

        /// <summary>
        /// 使用Swagger以及UI
        /// </summary>
        /// <param name="app"></param>
        public static void UseJuCheapSwagger(this IApplicationBuilder app)
        {
            //Enable middleware to serve generated Swagger as a JSON endpoint.
            app.UseSwagger();
            //Enable middleware to serve swagger-ui (HTML, JS, CSS etc.), specifying the Swagger JSON endpoint
            app.UseSwaggerUI(option =>
            {
                option.SwaggerEndpoint("/swagger/sparktodo/swagger.json", "JuCheap Api Documents");
                //如果设置根目录为swagger,将此值置空
                option.RoutePrefix = string.Empty;
                option.DocumentTitle = "JuCheap API";
            });
        }

        /// <summary>
        /// Api参数模型验证
        /// </summary>
        /// <param name="services"></param>
        public static void AddJuCheapModelValidate(this IServiceCollection services)
        {
            services.Configure<ApiBehaviorOptions>(options =>
            {
                options.InvalidModelStateResponseFactory = (context) =>
                {
                    var errors = context.ModelState.Values.SelectMany(x => x.Errors.Select(p => p.ErrorMessage)).ToList().Join(",");
                    var json = new ResponseJsonData<string> { Status = (int)HttpStatusCode.BadRequest, Message = errors };
                    return new JsonResult(json);
                };
            });
        }

        /// <summary>
        /// 添加IdentityServer 4认证服务
        /// </summary>
        /// <param name="services"></param>
        /// <param name="configuration"></param>
        public static void AddJuCheapAuthenticatiaon(this IServiceCollection services, IConfiguration configuration)
        {
            //IdentityServer 4 用户信息校验服务配置
            services.AddAuthentication(options =>
            {
                options.DefaultScheme = IdentityServerAuthenticationDefaults.AuthenticationScheme;
                options.DefaultChallengeScheme = nameof(JuCheapApiAuthenticationHandler);
                options.DefaultForbidScheme = nameof(JuCheapApiAuthenticationHandler);
            })
            .AddJwtBearer(IdentityServerAuthenticationDefaults.AuthenticationScheme, options =>
            {
                options.Authority = configuration.GetValue<string>("IdentityServerUrl").TrimEnd('/');
                options.RequireHttpsMetadata = false;
                options.Audience = configuration.GetValue<string>("Api:Id");
            })
            .AddScheme<AuthenticationSchemeOptions, JuCheapApiAuthenticationHandler>(nameof(JuCheapApiAuthenticationHandler), o => { });
        }

        /// <summary>
        /// 认证授权
        /// </summary>
        /// <param name="app"></param>
        public static void UseJucheapAuthentication(this IApplicationBuilder app)
        {
            app.UseAuthentication();
            app.UseAuthorization();
        }
    }
}
